home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
make.arc
/
MAKE.DOC
next >
Wrap
Text File
|
1986-02-19
|
26KB
|
859 lines
NDMAKE version 3.0
------------------
Copyright (C) 1985, 1986 D. G. Kneller
All rights reserved.
Program Description
-------------------
NDMAKE is an implementation of the UN*X program maintenance utility
called `make'. It has the same syntax and most of the capability. If
you are familiar with UN*X `make' you should have no difficulties with
NDMAKE. In the rest of this documentation, NDMAKE will be referred to
simply as `MAKE'.
MAKE is a utility that helps you maintain programs, particularly
programs that are composed of several modules (files). Once you
describe the relationships between these modules, MAKE will keep track
of the modules and only `make' those that are out of date with respect
to their sources. MAKE can also be used as a general compile and link
tool for handling single files, much like a batch file.
MAKE requires at least DOS 2.0 and uses a minimum of about 30000 bytes
of memory. Since MAKE executes other programs from within itself,
this memory will be unavailable to them while MAKE is running. Also,
since MAKE uses the file time to determine which files are newer, it
is imperative that you either have a real-time clock or are diligent
about setting the time and date when you boot up.
Synopsis
--------
make [-f makefile] [options] [macros] [targets]
The [] signify optional parameters. [options] and [macros] will be
discussed later.
Description
-----------
MAKE executes commands in a MAKE description file to update one or
more targets. The targets are typically the names of programs. If no
-f option is present, the MAKE description file called `makefile' is
tried. If makefile is `-', the keyboard (standard input) is used as
the makefile. More than one -f option may appear.
Make updates a target if it is older than the files it depends on, or
if the target does not exist. If no targets are given on the command
line, the first target in the makefile is `made'.
NDMAKE v3.0 page 2
The MAKE description files
--------------------------
MAKE uses 2 description files: `makefile' and `make.ini'. The
description files consists of several kinds of entries:
1) dependency and command lines
2) macro definitions
3) default rules
4) "dot commands"
When MAKE starts up, it looks for an initialization file called
`make.ini'. This file usually contains only default rules and macro
definitions that you don't want to put in every makefile. The current
directory is searched first, followed by directories along the PATH.
You customize your copy of MAKE by changing `make.ini'.
1) Dependency and command lines
-------------------------------
These are lines that specify the relationship between targets and
dependents, and how to update the targets. The general form is:
targets : [dependents]
[<tab>command]
....
where <tab> is the tab character.
The first line of an entry is a blank-separated list of targets, then
a colon, then a list of prerequisite files. All following lines that
begin with a tab are commands to be executed to update the target.
For example, assume you have a program `test.exe' that is composed of
modules `main.obj' and `sub.obj'. Each of these depend on a common
include file, `incl.h', and on their respective `.c' files. The
makefile might look like:
test.exe : main.obj sub.obj
link main.obj sub.obj, test;
main.obj : main.c incl.h
msc -AL main.c;
sub.obj : sub.c incl.h
msc -AL sub.c;
If a target appears on the left of more than one `colon' line, then it
depends on all of the names on the right of the colon on those lines,
but only one command sequence may be specified for it. The previous
example could have been written as:
test.exe : main.obj sub.obj
link main.obj sub.obj, test;
NDMAKE v3.0 page 3
main.obj : main.c
msc -AL main.c;
sub.obj : sub.c
msc -AL sub.c;
main.obj sub.obj : incl.h
A target that has no dependents is considered always out of date and
is always made. On the command line, wildcard characters can be given
in target names provided there are files to match the wildcards.
2) Macro definitions
--------------------
Makefile entries of the form:
name = [value]
are macro definitions. Macros allow the association of a name and a
value. Subsequent appearances of $(name) or ${name} are replaced by
value. If name is a single character, the parentheses or braces are
optional. Spaces between name and =, and between = and value are
ignored. If value is not given, the macro value is a null string.
The previous example could have had:
OBJS = main.obj sub.obj
test.exe : $(OBJS)
link $(OBJS), test;
main.obj : main.c
msc -AL main.c;
sub.obj : sub.c
msc -AL sub.c;
$(OBJS) : incl.h
Macros can be entered as command line parameters. For example:
A> make CFLAGS=-AL test.exe
MAKE evaluates macros only when needed, and the order in which macros
appear in a description file is insignificant. Conventionally, all
definitions appear at the top of the description file. If the same
name is defined more than once, the most recent definition is used.
The precedence of definitions is:
NDMAKE v3.0 page 4
1. command line definition (highest)
2. `makefile' definition
3. `make.ini' definition
4. environment definition (lowest)
Predefined macros:
There are 4 "run-time" macros. These are:
$* - stands for the target name with suffix deleted
$@ - stands for the full target name
$< - stands for the complete list of prerequisites
$? - stands for the list of prerequisites that are out
of date with respect to the target.
These are usually used when defining default rules (to be discussed
next). Unlike UN*X make, you can use these run-time macros anywhere
they make sense. Thus, a dependency line for OBJS could be:
$(OBJS) : $*.c
The macro `MFLAGS' gets filled in with the initial command line
options supplied to MAKE. This can be used to invoke MAKE on
makefiles in subdirectories and pass along the options. The macro
`CWD' gets filled in with the current directory.
The macro `$$' evaluates to the dollar sign `$'.
3) Default rules
----------------
MAKE can use default rules to specify commands for files for which the
makefile gives no explicit commands. A default rule tells MAKE how to
create a file with a particular extension from a file with the same
base name but another extension. Default rules take the following
form:
.from_extension.to_extension :
command
[command]
...
For example, to produce a `.obj' file from a `.c' file, the default
rule could be:
.c.obj :
msc -AL $*.c;
When MAKE finds a dependency with no commands, it looks for the first
possible name for which both a rule and a file exist. Since there may
be several ways to produce a `.obj' file (eg from a C, FORTRAN, or
NDMAKE v3.0 page 5
PASCAL compiler, or from MASM), the order in which rules are attempted
is specified by the `.SUFFIXES' list. This is a special target with a
list of extensions. For example:
.SUFFIXES: .exe .obj .c .asm .for
If MAKE was trying to make a `test.obj' file using a default rule, it
would first look for a `.c.obj' rule. If it found a `.c.obj' rule, it
would check if the file `test.c' existed. If it didn't, MAKE would
look for a `.asm.obj' rule (and `test.asm' file), and finally a
`.for.obj' rule (and `test.for' file).
Assuming `make.ini' contained the .c.obj rule and the .SUFFIXES as
defined above, our previous example could be written more succinctly:
OBJS = main.obj sub.obj
test.exe : $(OBJS)
link $(OBJS), test;
$(OBJS) : incl.h
Because of the default rules, `main.obj' and `sub.obj' implicitly
depend on files `main.c' and `sub.c', respectively, as well as
explicitly depending on `incl.h'.
Suffixes accumulate, so if the makefile had the line:
.SUFFIXES : .obj .pas
the suffix list would look like: .obj .pas .exe .obj .c .asm .for
A .SUFFIXES line with nothing on it clears the list of suffixes.
4) "dot commands"
-----------------
Besides the special target `.SUFFIXES' mentioned above, there are a
few other special targets and dependents that can be put in MAKE
description files.
.HELP - prints a reminder that `make -h' gives help.
.IGNORE - Commands returning nonzero status (ie. the exit code or
errorlevel) cause MAKE to terminate unless the special target
`.IGNORE' is in makefile or the command begins with `-' (hyphen).
.SILENT - Commands to be executed are printed when executed unless the
special target `.SILENT' is in makefile, or the first character of the
command is `@'. For example:
NDMAKE v3.0 page 6
all.exe : 1.obj 2.obj 3.obj
link 1 2 3, tmp.exe; # this line will be printed
- exepack tmp.exe all.exe # ignore any errors
@erase tmp.exe # this line will not be printed
.PRECIOUS - Break (control-C) and command errors cause the target to
be deleted unless the target has no dependents (explicit or implicit),
or depends on the special name `.PRECIOUS'. For example:
nerase.exe : nerase.obj .PRECIOUS # nerase.exe won't be deleted if
link nerase; # link returns an error.
Additional notes and technical information
------------------------------------------
If you type in a `makefile' from the keyboard (by using the command
`make -f -'), to signal you are done put a ^Z (control-Z) followed by
a <RETURN> as the last two characters.
Lines in a MAKE description file that are too long to fit on one line
can be extended to the next line by putting a backslash, `\', as the
last character of the line.
Everything on a line after the comment character, `#', is ignored.
Blank lines and lines that start with `#' are completely ignored.
Case is not important, so `test.obj' and `TEST.OBJ' are the same.
The separation character between targets and dependents, `:' is also
the character used for the drive separator in MSDOS. For MAKE to know
this colon is *not* the drive separator, it must be followed by a
space, semicolon or colon (see below), or nothing.
MAKE is stupid in that after the commands to update a target have been
executed without error, MAKE assumes the target is up to date. If you
give commands that don't really update a target, MAKE doesn't know.
When MAKE executes commands, such as `link', it first tries to find a
file called `link.exe' (or `link.com'). If the file is not found,
MAKE loads a second copy of COMMAND.COM and passes it the command
line, in the hope that the command is an internal DOS command. This
is backwards to how COMMAND.COM normally works (first checking
internally, then checking externally). It is done this way because I
could not get the second copy of COMMAND.COM to return the exit code
of the passed command. I'm using Microsoft C v3.0 and PCDOS 2.0, so
if anyone knows how to get the exit code back, please let me know.
You can force MAKE to load a second copy of COMMAND.COM by putting a
`+' as the first letter in the command. You can put more than one of
`-', `@', and `+' for each command. Ex:
NDMAKE v3.0 page 7
@- exepack tmp.exe all.exe
MAKE always uses a second copy of COMMAND.COM if the command involves
redirection of IO (with `>', `>>', `<', or `|').
Most commands must be shorter than the DOS command line limit of 128
characters. Since `link' is used so often, MAKE knows about it
specially and will automatically use a response file if the `link'
command is longer than the limit.
Macro definitions can refer to other macros. You could have:
CFLAGS = -A$(MODEL) -Od # remember, order is not important
MODEL = L
When it comes time to use CFLAGS, MAKE will expand CFLAGS as
`-AL -Od'. Command line macros have the highest precedence, so:
A> make MODEL=S test.exe
results in CFLAGS having the value `-AS -Od'. For command line macros
that contain spaces, enclose entirely the macro in double quotes, " ":
A> make "CFLAGS=-A$(MODEL) -Zd" MODEL=M test.exe
MAKE will let you define a recursive macro:
macro1 = $(macro2) # macro1 = the value of macro2
macro2 = $(macro1) # macro2 = the value of macro1
but generate an error if it tries to use it.
UN*X features
-------------
As with UN*X, dependency lines and default rules can have a command on
the same line as the `colon' line, if the command follows a semicolon:
.c.obj:; msc $*.c;
test.exe: $(OBJS); link $(OBJS), test;
@echo done
# are equivalent to
.c.obj:
msc $*.c;
test.exe: $(OBJS)
link $(OBJS), test;
@echo done
If a name appears on a line with a double colon :: then the command
sequence following that line is performed only if the name is out of
date with respect to the names to the right of the double colon, and
NDMAKE v3.0 page 8
is not affected by other double colon lines on which that name may
appear. Consider the following makefile:
1:: 2
@echo 2
1:: 3
@echo 3
If 2 and 3 are more recent than 1 and you type:
A> make 1
The response will be:
2
3
If 1 is more recent than 3, but 2 is newer than 1 the response is:
2
If 1 is more recent than both 2 and 3, the response will be:
Make: `1' is up to date.
OPTIONS
-------
Options are entered on the command line with a `-' preceding them.
You cannot use `/' instead of `-'. -nd is equivalent to -n -d.
-d Debug mode. Prints information on macros, dependencies,
SUFFIXES, default rules. Also traces MAKE as it excutes.
-h Print a help screen. Also, -? will do the same.
-i Equivalent to the special entry `.IGNORE'. Causes commands
that return errors to be ignored. Doing `make -i > errs'
collects all error messages into 1 `errs' file. To stop
running `make -i' you may have to push ^C several times.
-k When a command returns nonzero status, abandon work on the
current target, but continue on branches that do not depend
on the current target.
-n Display but do not execute the commands needed to update the
targets. Doing `make -n > todo.bat' produces the batch file
`todo.bat' containing the commands to be executed.
-r Clears the .SUFFIXES list after `make.ini' is read.
-s Equivalent to the special entry `.SILENT'. Commands are not
echoed to the screen before they are executed.
-t Touch, i.e. set the file time of the out of date targets to
the current time without executing any commands.
NDMAKE v3.0 page 9
Sample session
--------------
A sample `make.ini' file
------------------------
.SUFFIXES : .exe .obj .c .for .asm
M = S
CFLAGS = -A$M
.c.obj:; cl $(CFLAGS) -c $*.c
.obj.exe:; link $*.obj, $@;
.c.exe:
cl $(CFLAGS) -c $*.c
link $*.obj, $@;
erase $*.obj
A sample makefile
-----------------
OBJS = main.obj sub.obj
test.exe: $(OBJS)
link $<, $@;
$(OBJS): incl.h
sub.obj: sub.c
cl $(CFLAGS) -Od -c sub.c
install: test.exe
copy test.exe $(BIN) # BIN comes from the environment
----------
Assume the following files are in your directory: `main.c', `sub.c',
`incl.h'. When you type:
A> make
MAKE first reads `make.ini' then `makefile'. It sees the first target
`test.exe' and tries to make it. But first, MAKE must know if the
files that `test.exe' depends on are up to date. As `test.exe'
depends on several `.obj' files, and these `.obj' files also have
dependents, the (very) detailed procedure that MAKE undergoes looks
like this:
-Make `test.exe'
`test.exe' depends on `main.obj' and `sub.obj'. Make each of these
-Make `main.obj'
`main.obj' depends on `incl.h'.
-Make `incl.h'
`incl.h' depends on nothing explicitly.
NDMAKE v3.0 page 10
-Since there are no explicit commands to make `incl.h',
check for implicit dependencies.
-Since there is no `.h' suffix in .SUFFIXES, there are
no implicit dependencies.
-Assume `incl.h' is up to date.
-Since there are no explicit commands for `main.obj', check for
implicit dependencies based on default rules.
-Find the rule `.c.obj' and the file `main.c'.
-Make `main.c'
`main.c' depends on nothing explicitly.
-Since there are no explicit commands to make `main.c',
check for implicit dependencies.
-Since there are no `.from_extension.c' rules, `main.c'
depends on nothing implicitly.
-Assume `main.c' is up to date.
-Compare `main.obj' with `incl.h' and `main.c'. Since `main.obj'
doesn't exist, it is out of date with respect to its dependents,
so execute the (implicit) command:
cl -AL -c main.c
-Assume `main.obj' is up to date.
-Make `sub.obj'
`sub.obj' depends on `incl.h' and `sub.c'
-Make `incl.h'
MAKE already knows that `incl.h' is up to date.
-Make `sub.c'
`sub.c' depends on nothing explicitly
-Since there are no explicit commands to make `sub.c',
check for implicit dependencies.
-Since there are no `.from_extension.c' rules, `sub.c'
depends on nothing implicitly.
-Assume `sub.c' is up to date.
-Compare `sub.obj' with `incl.h' and `sub.c'. Since `sub.obj'
doesn't exist, it is out of date with respect to its dependents,
so execute the (explicit) command:
cl -AL -Od -c sub.c
-Assume `sub.obj' is up to date.
-Compare `test.exe' with `main.obj' and `sub.obj'. Since `test.exe'
doesn't exist, execute the command:
link main.obj sub.obj, test.exe;
-Assume `test.exe' is up to date.
Note the way $< gets replaced with the files `test.exe' depends on,
and $@ gets replaced with `test.exe'.
Assuming no errors occurred, when you now type `make' you will get the
message that `test.exe' is up to date. If you edit `sub.c' and make
some changes, when you next type `make', MAKE will see that `sub.c' is
NDMAKE v3.0 page 11
more recent than `sub.obj' and recompile `sub.c'. MAKE will then see
that `sub.obj' is more recent than `test.exe' and relink the files.
If you type `make install', MAKE will ensure `test.exe' is up to date,
then copy it to your BIN directory. BIN was assumed to be defined in
your environment.
Using MAKE without a makefile
-----------------------------
It is possible to use MAKE without having a makefile. Assume you have
a file called `xyzzy.c' and using the same `make.ini' file described
above, you type:
A> make xyzzy.exe
MAKE uses its default rules to compile `xyzzy.c', link `xyzzy.obj' to
form `xyzzy.exe', then erases `xyzzy.obj'. If several `.exe' files
exist in a directory and you have just finished editing some of their
`.c' files, you could type:
A> make *.exe
and update only the `.exe' files that are out of date. By adding more
default rules to `make.ini', MAKE could invoke the FORTRAN compiler
for `.for' files or MASM for `.asm' files. In this way, MAKE can do
the right thing for each type of file. You can do `make *.exe' and
have MAKE figure out what to do.
NDMAKE v3.0 page 12
USER-SUPPORTED SOFTWARE NOTIFICATION
------------------------------------
If you like and use this program, I ask you to consider registering
it. The benefits of registration include the first bugfix/enhanced
version free. Registered owners will get a response to any questions
they may have. I anticipate adding VPATH (a way to look for dependent
files in other than the current directory) and ARC and LIB support for
the next version. Also, I am certain there will be some reported bugs
or incompatibilities with UN*X MAKE which will be fixed in the first
update.
The suggested registration fee is $20. Regardless of whether you
register or not, you may freely copy and distribute this program for
noncommercial purposes. The program, MAKE.EXE, the documentation,
MAKE.DOC, and the initialization file, MAKE.INI must all be
distributed together.
Commercial use of this program requires my prior written consent.
I hope you enjoy NDMAKE and find it to be a useful addition to your
programming tools.
NDMAKE v3.0 page 13
---------------------------------------------------------------------
Registration form for NDMAKE v3.0
Name: _________________________________________________
Address: _________________________________________________
City, State, Zip: _________________________________________________
Country: _________________________________________________
OPTIONAL: System description (computer, memory, DOS version)
_____________________________________________________________________
_____________________________________________________________________
COMMENTS: Please feel free to add your thoughts or suggestions!
_____________________________________________________________________
_____________________________________________________________________
_____________________________________________________________________
_____________________________________________________________________
Mail to:
D. G. Kneller
2 Panoramic Way #204
Berkeley CA, 94704
U.S.A